import { find, some } from 'lodash-es'
import { CurrencyCryptoEnum, CurrencyEnum, currencyPrecision } from '@/enums'
import { useCurrencyStore, useWalletStore } from '@/store'
import { Decimals } from '@/utils/decimal.ts'

export const fmtBalance = (value: string | number, currency: CurrencyEnum) => {
	// 根据产品需求展示 指定小数位 或默认 法币展示2位小数,加密币展示8位小数
	let minFD = currencyPrecision[currency] ?? 8
	let maxFD = currencyPrecision[currency] ?? 8
	if (isFiatCurrency(currency)) {
		minFD = currencyPrecision[currency] ?? 2
		maxFD = currencyPrecision[currency] ?? 2
	}
	const format = new Intl.NumberFormat('en-US', {
		minimumFractionDigits: minFD,
		maximumFractionDigits: maxFD,
		// 金额按照要求的小数位截断显示,不要四舍五入
		roundingMode: 'trunc'
	} as any)
	return format.format(+value)
}

function formatToFixedDecimals(num: number, digits: number) {
	// 使用 Math.trunc 来截断多余的位数，确保不四舍五入
	const factor = Math.pow(10, digits)
	return (Math.trunc(num * factor) / factor).toFixed(digits)
}

export const fmtBalanceDecimal = (value: string | number, currency: CurrencyEnum) => {
	// 根据产品需求展示 指定小数位 或默认 法币展示2位小数,加密币展示8位小数
	const precision = currencyPrecision[currency] ?? (isFiatCurrency(currency) ? 2 : 8)
	return formatToFixedDecimals(Number(value), precision)
}

export const calcExchangeRate = (
	currencyFrom: CurrencyEnum,
	currencyTo: CurrencyEnum,
	amountFrom: number | string
) => {
	const currencyStore = useCurrencyStore()
	if (currencyStore.loading.exchangeRate) return amountFrom
	if (currencyFrom === currencyTo) return amountFrom
	const mul = currencyStore.exchangeRate[currencyFrom]?.[currencyTo]
	const div = currencyStore.exchangeRate[currencyTo]?.[currencyFrom]
	if (mul) return Decimals.mul(amountFrom, mul)
	if (div) return Decimals.div(amountFrom, div)
	console.warn(`转换汇率缺失:从[ ${currencyFrom} ]到[ ${currencyTo} ]`)
	return NaN
}

export const calcCurrencyType = (currency: CurrencyEnum) => {
	// 资产类型:1-虚拟币钱包，2-法币钱包
	const currencyStore = useCurrencyStore()
	if (some(currencyStore.cryptoList, { currency })) return 1
	if (some(currencyStore.fiatList, { currency })) return 2
	return 1
}

export const isFiatCurrency = (currency: CurrencyEnum) => {
	const currencyStore = useCurrencyStore()
	return some(currencyStore.fiatList, { currency })
}

/**
 * @description 计算金额: 经过汇率转换 和 法币开关控制
 * @description 输出的金额是数值格式,方便用于计算或是输入框
 * @description 想要展示的格式可以用fmtBalance方法处理
 * @param amount
 * @param currency
 * @param currencyTo
 * @param reverseFiat 法币显示开启的时候，展示虚拟币；关闭的时候展示法币
 * @param showSymbol 用于不开启法币 && 不反转 时显示货币符号
 */
export const calcAmount = (
	amount: number | string,
	currency: CurrencyEnum,
	currencyTo?: CurrencyEnum,
	reverseFiat: boolean = false,
	showSymbol: boolean = false
) => {
	const walletStore = useWalletStore()
	const currencyStore = useCurrencyStore()
	const result = {
		amount: amount,
		currency: currency,
		currencySymbol: '',
		currencyTo: <CurrencyEnum>(currencyTo || currency)
	}
	const { displayCryptoInFiat, selectedFiatCurrency } = walletStore.walletConfig
	if (displayCryptoInFiat || reverseFiat || currencyTo) {
		// 开启法币展示时始终展示法币换算为法币的单位
		result.currencyTo =
			displayCryptoInFiat || reverseFiat ? selectedFiatCurrency : result.currencyTo
		if (displayCryptoInFiat && reverseFiat) {
			result.amount = calcExchangeRate(result.currencyTo, currency, amount)
		} else {
			result.amount = calcExchangeRate(currency, result.currencyTo, amount)
		}
		// 反转货币符号
		if (displayCryptoInFiat && reverseFiat) {
			const _c = result.currency
			result.currency = result.currencyTo
			result.currencyTo = _c
		}
	}
	// 开启法币 || 反转显示示时 显示货币符号
	if (displayCryptoInFiat || reverseFiat || showSymbol) {
		const c = displayCryptoInFiat && reverseFiat ? currency : result.currencyTo
		const item = find([...currencyStore.fiatList, ...currencyStore.cryptoList], { currency: c })
		result.currencySymbol = item?.currencySymbol || c || ''
	}
	return result
}

// 获取货币图标
export const getCurrencyIcon = (_currency?: CurrencyEnum) => {
	const walletStore = useWalletStore()
	const currencyStore = useCurrencyStore()
	const { cryptoList, fiatList } = currencyStore
	const currency = _currency || walletStore.balanceCur?.currency || CurrencyCryptoEnum.USDT
	const item = find([...fiatList, ...cryptoList], { currency })
	return item?.icon || ''
}
